#pragma once

#include "actor.h"

class TestReplication
{
	class TestReplica
	{
	public:
		TestReplica ()
		: attribute ( 0 )
		{
		}
		int attribute;
	};
	
	class TestActor
	: public Actor < TestActor, TestReplica >
	, public TestReplica
	{
		virtual void UpdateReplica ( TestReplica & replica ) const
		{
			replica = * this;
		}
	};
	
	class TestActorsFactory
	: public ActorsFactory < TestActor, TestReplica >
	{
	public:
		Id Create ()
		{
			return RegisterNewActor ( new TestActor () );
		}
	};
	
	class SetAttribute
	: public Message < TestActor, TestReplica >
	{
		SetAttribute ( int value )
		: newValue ( value )
		{
		}
		virtual void Execute ( TestActor & actor )
		{
			actor.attribute = newValue;
		}
	public:
		static void SendTo ( TestActor::Id & actor, int attribute )
		{
			SendNewMessage ( actor, new SetAttribute ( attribute ) );
		}
	private:
		int newValue;
	};
	
public:
	static void Run ()
	{
		TestActorsFactory factory;
		TestActor::Id actorId = factory.Create ();
		const TestReplica & repl = * actorId.GetReplica ();
		
		SetAttribute::SendTo ( actorId, 1 );
		factory.HandleMessages ();
		assert ( repl.attribute == 0 );
		factory.UpdateReplicas ();
		assert ( repl.attribute == 1 );
	}
};
